package com.ddzh.security;

import com.ddzh.utils.JwtTokenUtil;
import com.ddzh.vo.AuthMenuTreeVo;
import com.ddzh.web.AuthMenuTreeVoController;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
/**
 * 校验token的过滤器,因为当前使用的security框架中没有解析token的过滤器，所以我们一起加
 * OncePerRequestFilter:使过滤器只执行一次，避免过滤器执行两次的情况
 * */
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final String TOKEN_HEADER = "token";

    private Map<String , Map<String,String>> userMap = new HashMap<>();

    @Resource
    private AuthMenuTreeVoController authMenuTreeVoController;

    private boolean inited;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader(TOKEN_HEADER);
        try {
            if(token != null && "".equals(token.trim())==false){
                //解密token
                //数据库用户查询
                String username = JwtTokenUtil.parseToken(token);
                initUser(username);
                Map<String,String> userInfo = userMap.get(username);
                User user = null;
                if(userInfo != null){
                    user = new User(username,userInfo.get("password"),AuthorityUtils.commaSeparatedStringToAuthorityList(userInfo.get("roleNameList")));
                }
                RpcContext.getContext().setAttachment("currentUser",username);
                //身份信息处理
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                //把我们已经认证好的身份信息往下传递
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //过滤器放行
            filterChain.doFilter(request, response);
        }
    }

    private void initUser(String username){
        AuthMenuTreeVo authVo = authMenuTreeVoController.getAuthMenuByUsername(username);
        Map<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("password", passwordEncoder.encode(authVo.getPassword()));
        hashMap.put("roleNameList", authVo.getRoleNameList().toString());
        userMap.put(authVo.getUserName(), hashMap);
    }

}
